#ifndef FILE_Board_H
#define FILE_Board_H

#include "position_t.h"
#include <vector>

/**
 * This class contain the board data.
 *
 * By convention, x is the position on the horizontal axis in
 * [0,20[ (currently), and y  the position on the vertical axis,
 * in [0,12[ (currently).
 */
class Board{
public:
	/**
	 * Represents the states of a board's cases.
	 */
	enum case_e{
		CASE_EMPTY = 0,
		CASE_PAWN,
		CASE_BALL,
		CASE_OUT_OF_RANGE
	};
	/**
	 * The board's size on the horizontal axis.
	 */
	static const int w = 19;
	/**
	 * The board's size on the horizontal axis.
	 */
	static const int h = 11;
	/**
	 * Creates an empty board.
	 */
	Board();
	/**
	 * Trivial copy construction of a board.
	 * 
	 * A copy constucted board won't be linked in any way to the original
	 * board.
	 */
	Board(const Board& b);
	/**
	 * Trivial assignement of a board.
	 *
	 * A copy assigned board won't be linked in any way to the original
	 * board.
	 */
	Board& operator=(const Board& b);
	/**
	 * \return The given case value, or CASE_OUT_OF_RANGE if the position is
	 * not on the board.
	 */
	case_e getCase(position_t p) const ;
	/**
	 * Tests if the position is valid for the placing of a new pawn.
	 */
	bool isPawnPlacable(position_t p) const ;
	/**
	 * Tests if the position is valid for moving the ball there.
	 */
	bool isBallPlacable(position_t p) const ;
	/**
	 * Sets a board's case to the given value.
	 * \param val The value to give to the case.
	 * Must not be CASE_OUT_OF_RANGE.
	 * \return \c false if the case is not on the board.
	 */
	bool setCase(position_t p, case_e val);
	/**
	 * \return The ball position.
	 */
	position_t getBallPosition() const ;
	/**
	 * Set the ball position.
	 */
	bool setBallPosition(position_t p);
	/**
	 * \return \c true if the given position is onto the board.
	 */
	static bool onBoard(position_t p);
	/**
	 * \return \c true if when the ball is in this position, the
	 * game is over.
	 * \note If the position is beyond the goal zone, i.e. one case
	 * at each end of the board.
	 */
	static bool onGoalZone(position_t p);

	/**
	 * Tests the Board class.
	 */
	static int _runTests();
private:
	static int getItemsSize();
	case_e items[w][h];
	position_t ball;
};



#endif // FILE_Board_H